package com.xh.bussiness.tiku.util;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aspose.words.DocumentBuilder;
import com.xh.bussiness.tiku.bean.dto.QuestionDto;
import com.xh.bussiness.tiku.bean.dto.QuestionOptionDto;
import com.xh.bussiness.tiku.constant.PaperWidthConstant;
import com.xh.bussiness.tiku.constant.QuestionConstant;
import com.xh.bussiness.tiku.service.IQuestionService;
import com.xh.bussiness.tiku.service.IQuestionTypeRelationService;
import com.xh.core.util.OfficeUtils;
import com.xh.core.util.RegexUtils;
import com.xh.core.util.StringUtils;
import com.xh.tools.question.constant.QuestionTypeEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;

@Component
public class ExportQuestionUtils {
    private static IQuestionService _questionService;

    private static IQuestionTypeRelationService _questionTypeRelationService;

    @Autowired
    private IQuestionService questionService;
    @Autowired
    private IQuestionTypeRelationService questionTypeRelationService;

    @PostConstruct
    public void init() {
        _questionService = questionService;
        _questionTypeRelationService = questionTypeRelationService;
    }

    public static void createQuestion(Integer blankRowCount, String subjectId, String rootPath,  QuestionDto question, DocumentBuilder builder, Boolean withTitle, Boolean withAnswer, Boolean withAnalysis, Boolean withExamPoint) throws Exception {
        Integer questionType = question.getBasicQuestionType() != null ? question.getBasicQuestionType() : _questionTypeRelationService.queryToolQuestionTypeByJyType(question.getSubjectId(), question.getType());
        if (withTitle) {
            // 替换图片路径
            String title = replaceImgPath(rootPath, question.getTitle().trim()).replaceAll("<ol>||</ol>", "").replaceAll("<li", "<p").replaceAll("</li>", "</p>");
            String questionNo = questionType != null && !questionType.equals(QuestionTypeEnum.READING.getValue()) && !questionType.equals(QuestionTypeEnum.CLOZE.getValue()) ? question.getOrderNo() + 1 + "." : "";
            builder.insertHtml(questionNo + StringUtils.removeStartAndEndBlank(title));
            builder.writeln();
        }
        if (questionType == null) {
            questionType = QuestionTypeEnum.OTHER.getValue();
        }
        question.setBasicQuestionType(questionType);
        if (questionType == 1 || questionType == 2) {
            question.setOrderNo(question.getOrderNo() + 1);
            createSingleQuestion(blankRowCount, rootPath, question, builder, withTitle, withAnswer, withAnalysis, withExamPoint);
            return;
        }
        if (questionType == 9) {
            createReadingQuestion(blankRowCount, rootPath, question, builder, withTitle, withAnswer, withAnalysis, withExamPoint);
            return;
        }
        if (questionType == 10) {
            createCloneQuestion(blankRowCount, rootPath, question, builder, withTitle, withAnswer, withAnalysis, withExamPoint);
            return;
        }
        // 其他题型
        question.setOrderNo(question.getOrderNo() + 1);
        if (withAnswer) {
            JSONArray answers = (JSONArray) question.getRightAnswer();
            String answer = "";
            if (answers != null && answers.size() == 1) {
                answer = answers.getJSONObject(0).getString("content");
            }
            // 填空题多个答案
            if (answers != null && answers.size() > 1) {
                for (int i = 0; i < answers.size(); i++) {
                    JSONObject json = answers.getJSONObject(i);
                    answer += "(" + (i + 1) + ")" + json.getString("content");
                    if (i < answers.size() - 1) {
                        answer += "<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
                    }
                }
            }

            String index = withTitle ? "" : question.getOrderNo() + ".";
            builder.insertHtml(index + "【答案】" + answer);
            builder.writeln();
        }
        if (withAnalysis) {
            builder.insertHtml("【解析】" + (question.getAnalysis() == null ? "" : question.getAnalysis()));
            builder.writeln();
        }
        // 解答题留空行
        if (blankRowCount != null && blankRowCount > 0) {
            for (Integer i = 0; i < blankRowCount; i++) {
                builder.writeln();
            }
        }
    }

    public static void createSingleQuestion(Integer blankRowCount, String rootPath, QuestionDto question, DocumentBuilder builder, Boolean withTitle, Boolean withAnswer, Boolean withAnalysis, Boolean withExamPoint) throws Exception {
        JSONArray options = (JSONArray) question.getOption();
        if (null == options) {
            return;
        }
        if (withTitle) {
            List<QuestionOptionDto> optionDtos = JSONObject.parseArray(question.getOption().toJSONString(), QuestionOptionDto.class);
            Integer optionNum = QuestionUtils.calculateOptionArrange(optionDtos);
            for (int k = 0; k < optionDtos.size(); k++) {
                QuestionOptionDto questionOptionDto = optionDtos.get(k);
                int index = questionOptionDto.getNo();
                String name = QuestionConstant.OPTION_ORDER.substring(index - 1, index);
                String content = StringUtils.removeStartAndEndBlank(name + "." + replaceImgPath(rootPath, questionOptionDto.getContent()));
                if (optionNum == 1) {
                    builder.insertHtml(content);
                    if (k != optionDtos.size() - 1){
                        builder.writeln();
                    }
                } else if (optionNum == 2) {
                    if (k == 0) {
                        OfficeUtils.createTab(builder, 1);
                    }
                    builder.insertHtml(content);
                    // k 为2的倍数时，添加tab
                    if (k % 2 == 0) {
                        builder.write("\t");
                    }
                    // k不为2的倍数时，换行
                    if (k != optionDtos.size() - 1 && k % 2 == 1) {
                        builder.writeln();
                    }
                } else {
                    if (k == 0) {
                        OfficeUtils.createTab(builder, 3);
                    }
                    builder.insertHtml(content);
                    if (k != optionDtos.size() - 1) {
                        builder.write("\t");
                    }
                    // 超过四个的选项换行显示
                    if (k != optionDtos.size() - 1 && k % 4 == 3) {
                        builder.writeln();
                    }
                }
            }
            builder.writeln();
        }
        if (withAnswer) {
            JSONArray answers = (JSONArray) question.getRightAnswer();
            String answer = "";
            if (answers != null && answers.size() > 0) {
                answer = answers.getJSONObject(0).getString("content");
            }
            String index = withTitle ? "" : question.getOrderNo() + ".";
            builder.insertHtml("【答案】" + replaceImgPath(rootPath, answer));
            builder.writeln();
        }
        if (withAnalysis) {
            builder.insertHtml("【解析】" + replaceImgPath(rootPath, question.getAnalysis()));
            builder.writeln();
        }
        // 解答题留空行
        if (blankRowCount != null && blankRowCount > 0) {
            for (Integer i = 0; i < blankRowCount; i++) {
                builder.writeln();
            }
        }
    }

    public static void createCloneQuestion(Integer blankRowCount, String rootPath, QuestionDto question, DocumentBuilder builder, Boolean withTitle, Boolean withAnswer, Boolean withAnalysis, Boolean withExamPoint) throws Exception {
        JSONArray options = (JSONArray) question.getOption();
        List<Integer> indexs = new ArrayList<>();
        if (withTitle && null != options) {
            for (int i = 0; i < options.size(); i++) {
                indexs.add(question.getOrderNo() + 1);
                question.setOrderNo(question.getOrderNo() + 1);
                // 题号列
                JSONObject option = options.getJSONObject(i);
                JSONArray childs = option.getJSONArray("childs");
                //判断选项排列
                List<QuestionOptionDto> optionDtos = JSONObject.parseArray(option.getString("childs"), QuestionOptionDto.class);
                Integer optionNum = QuestionUtils.calculateOptionArrange(optionDtos);
                for (int k = 0; k < childs.size(); k++) {
                    if (k == 0) {
                        // 题号列
                        builder.write(question.getOrderNo() + ".");
                    }
                    JSONObject childOption = childs.getJSONObject(k);
                    int index = childOption.getInteger("no");
                    String name = QuestionConstant.OPTION_ORDER.substring(index - 1, index);
                    String content = name + "." + replaceImgPath(rootPath, childOption.getString("content"));
                    if (optionNum == 1) {
                        // 这个tab是为了把题号列单独显示出来
                        if (k == 0) {
                            OfficeUtils.createCloneTab(builder, 1);
                        }
                        builder.write("\t");
                        builder.insertHtml(content);
                        if (k != childs.size() - 1){
                            builder.writeln();
                        }
                    } else if (optionNum == 2) {
                        if (k == 0) {
                            OfficeUtils.createCloneTab(builder, 1);
                        }
                        // 这个tab是为了把题号列单独显示出来
                        if (k % 2 == 0) {
                            builder.write("\t");
                        }
                        builder.insertHtml(content);
                        // k 为2的倍数时，添加tab
                        if (k % 2 == 0) {
                            builder.write("\t");
                        }
                        // k不为2的倍数时，换行
                        if (k != optionDtos.size() - 1 && k % 2 == 1) {
                            builder.writeln();
                        }
                    } else {
                        if (k == 0) {
                            OfficeUtils.createCloneTab(builder, 3);
                        }
                        // 这个tab是为了把题号列单独显示出来
                        if (k % 4 == 0) {
                            builder.write("\t");
                        }
                        builder.insertHtml(content);
                        if (k != optionDtos.size() - 1) {
                            builder.write("\t");
                        }
                        // 超过四个的选项换行显示
                        if (k != optionDtos.size() - 1 && k % 4 == 3) {
                            builder.writeln();
                        }
                    }
                }
                builder.writeln();
            }
        }
        // 教师版
        if (withTitle && withAnswer) {
            JSONArray answers = (JSONArray) question.getRightAnswer();
            String answer = "";
            Integer startIndex = indexs.isEmpty() ? 1 : indexs.get(0);
            Integer endIndex = indexs.isEmpty() ? answers.size() : indexs.get(indexs.size()-1);
            if (answers != null && answers.size() > 0) {
                for (int i = 0; i < answers.size(); i++) {
                    JSONObject json = answers.getJSONObject(i);
                    String content = json.getString("content");
                    if (i % 5 == 0) {
                        if (i != 0) {
                            answer += "   ";
                        }
                        if ((i / 5) * 5 + 5 < answers.size()) {
                            answer += ((i / 5) * 5 + startIndex) + "-" + ((i / 5) * 5 + 5 + startIndex - 1) + " ";
                        } else {
                            answer += ((i / 5) * 5 + startIndex) + "-" + endIndex + " ";
                        }
                    }
                    answer += content;
                }
            }
            builder.writeln("【答案】" + answer);
        }
        // 解析版
        if (!withTitle && withAnswer) {
            for (int i = 0; i < options.size(); i++) {
                indexs.add(question.getOrderNo() + 1);
                question.setOrderNo(question.getOrderNo() + 1);
            }
            JSONArray answers = (JSONArray) question.getRightAnswer();
            String answer = "";
            Integer startIndex = indexs.isEmpty() ? 1 : indexs.get(0);
            Integer endIndex = indexs.isEmpty() ? answers.size() : indexs.get(indexs.size()-1);
            if (answers != null && answers.size() > 0) {
                for (int i = 0; i < answers.size(); i++) {
                    JSONObject json = answers.getJSONObject(i);
                    String content = json.getString("content");
                    if (i % 5 == 0) {
                        if (i != 0) {
                            answer += "   ";
                        }
                        if ((i / 5) * 5 + 5 < answers.size()) {
                            answer += ((i / 5) * 5 + startIndex) + "-" + ((i / 5) * 5 + 5 + startIndex - 1) + " ";
                        } else {
                            answer += ((i / 5) * 5 + startIndex) + "-" + endIndex + " ";
                        }
                    }
                    answer += content;
                }
            }
            builder.writeln("【答案】" + answer);
        }
        if (withAnalysis) {
            builder.insertHtml("【解析】" + replaceImgPath(rootPath, question.getAnalysis()));
            builder.writeln();
        }
        // 解答题留空行
        if (blankRowCount != null && blankRowCount > 0) {
            for (Integer i = 0; i < blankRowCount; i++) {
                builder.writeln();
            }
        }
    }

    public static void createReadingQuestion(Integer blankRowCount, String rootPath, QuestionDto question, DocumentBuilder builder, Boolean withTitle, Boolean withAnswer, Boolean withAnalysis, Boolean withExamPoint) throws Exception {
        //选项
        List<QuestionDto> childQuestion = _questionService.getQuestionChild(question.getId());
        if(CollectionUtils.isEmpty(childQuestion)){
            return;
        }
        List<Integer> indexs = new ArrayList<>();
        if (withTitle) {
            for (int i = 0; i < childQuestion.size(); i++) {
                indexs.add(question.getOrderNo() + 1);
                question.setOrderNo(question.getOrderNo() + 1);
                QuestionDto questionDto = childQuestion.get(i);
                if (question.getTitle().trim().startsWith("<p>")) {
                    question.setTitle(question.getTitle().trim().replaceFirst("<p>", "").replaceFirst("</p>", ""));
                }
                builder.insertHtml(question.getOrderNo() + "." + replaceImgPath(rootPath, questionDto.getTitle().trim()));
                builder.writeln();
                JSONArray options = (JSONArray) questionDto.getOption();
                if (null == options) {
                    continue;
                }
                List<QuestionOptionDto> optionDtos = JSONObject.parseArray(questionDto.getOption().toJSONString(), QuestionOptionDto.class);
                Integer optionNum = QuestionUtils.calculateOptionArrange(optionDtos);
                for (int k = 0; k < optionDtos.size(); k++) {
                    QuestionOptionDto questionOptionDto = optionDtos.get(k);
                    int index = questionOptionDto.getNo();
                    String name = QuestionConstant.OPTION_ORDER.substring(index - 1, index);
                    String content = name + "." + replaceImgPath(rootPath, questionOptionDto.getContent());
                    if (optionNum == 1) {
                        builder.insertHtml(content);
                        builder.writeln();
                    } else if (optionNum == 2) {
                        if (k == 0) {
                            OfficeUtils.createTab(builder, 1);
                        }
                        builder.insertHtml(content);
                        // k 为2的倍数时，添加tab
                        if (k != optionDtos.size() - 1 && k % 2 == 0) {
                            builder.write("\t");
                        }
                        // k不为2的倍数时，换行
                        if(k % 2 == 1) {
                            builder.writeln();
                        }
                    } else {
                        if (k == 0) {
                            OfficeUtils.createTab(builder, 3);
                        }
                        builder.insertHtml(content);
                        if (k != optionDtos.size() - 1) {
                            builder.write("\t");
                        }
                        // 超过四个的选项换行显示
                        if (k % 4 == 3) {
                            builder.writeln();
                        }
                    }
                }
            }
            builder.writeln();
        }
        // 教师版
        if (withTitle && withAnswer) {
            JSONArray answers = (JSONArray) question.getRightAnswer();
            String answer = "";
            // 填空题多个答案
            if (answers != null && answers.size() > 1) {
                for (int i = 0; i < answers.size(); i++) {
                    JSONObject json = answers.getJSONObject(i);
                    answer += indexs.get(i) +"."+ json.getString("content");
                    if (i < answers.size() - 1) {
                        answer += "<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
                    }
                }
            }
            builder.insertHtml("【答案】" + replaceImgPath(rootPath, answer));
            builder.writeln();
        }
        // 解析版
        if (!withTitle && withAnswer) {
            for (int i = 0; i < childQuestion.size(); i++) {
                indexs.add(question.getOrderNo() + 1);
                question.setOrderNo(question.getOrderNo() + 1);
            }
            JSONArray answers = (JSONArray) question.getRightAnswer();
            if (answers != null && answers.size() > 0) {
                for (int i = 0; i < answers.size(); i++) {
                    JSONObject answer = answers.getJSONObject(i);
                    builder.insertHtml(indexs.get(i) + "." + "【答案】" + replaceImgPath(rootPath, answer.getString("content")));
                    builder.writeln();
                }
            }
        }
        if (withAnalysis) {
            builder.insertHtml("【解析】" + replaceImgPath(rootPath, question.getAnalysis()));
            builder.writeln();
        }
        // 解答题留空行
        if (blankRowCount != null && blankRowCount > 0) {
            for (Integer i = 0; i < blankRowCount; i++) {
                builder.writeln();
            }
        }
    }

    public static void formatQuestion(String subjectId, QuestionDto question) {
        // 处理题干中开头为P标签情况，P标签导致换行，和题号分离
        String title = question.getTitle();
        if (title.trim().startsWith("<p")) {
//            question.setTitle(title.trim().replaceFirst("<p>", "").replaceFirst("</p>", ""));
            question.setTitle(title.trim().replaceFirst("<p", "<span").replaceFirst("</p>", "</span>"));
        }
        // 目前只处理完形填空和阅读理解
        if (question.getBasicQuestionType() == null || !question.getBasicQuestionType().equals(QuestionTypeEnum.CLOZE.getValue()) && !question.getBasicQuestionType().equals(QuestionTypeEnum.READING.getValue())) {
            return;
        }
        // 处理完形填空和阅读理解，段落开头空2个字符
        String blankStr = subjectId.contains("chinese") && !subjectId.contains("yuwen") ? "&nbsp;&nbsp;" : "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
        if (question.getBasicQuestionType() != null && question.getBasicQuestionType().equals(QuestionTypeEnum.CLOZE.getValue())) {
            if (StringUtils.isNotEmpty(title)) {
                title = title.replace("<br>", "<br>" + blankStr).replace("<br/>", "<br>" + blankStr);
                if (title.startsWith("&nbsp;")) {
                    title = title.replaceFirst("[&nbsp;]+", blankStr);
                } else {
                    title = blankStr + title;
                }
                int index = question.getOrderNo();
                String replaceStr = "__<u>##</u>__";
                title = title.replaceAll(com.xh.tools.question.constant.QuestionConstant.REGEX_MATCH_RULE.CLOZE_BLANK_SELECT, replaceStr);
                Matcher childMatcher = RegexUtils.getMatcher(title, replaceStr);
                while (childMatcher.find()) {
                    String blank = childMatcher.group();
                    String newBlank = blank.replaceAll("##", String.valueOf(++index));
                    title = title.replaceFirst(blank, newBlank);
                }
                question.setTitle(title);
            }
        } else if (question.getBasicQuestionType() != null && question.getBasicQuestionType().equals(QuestionTypeEnum.READING.getValue())) {
            if (StringUtils.isNotEmpty(title)) {
                if (title.startsWith("&nbsp;")) {
                    title = title.replaceFirst("[&nbsp;]+", blankStr);
                } else {
                    title = blankStr + title;
                }
                title = title.replace("<br>", "<br>" + blankStr).replace("<br/>", "<br>" + blankStr);
                question.setTitle(title);
            }
        }
    }

    public static String replaceImgPath(String rootPath, String html) {
        if (StringUtils.isEmpty(html)) {
            return "";
        } else {
            html = html.replaceAll("<p style=\"margin-top:0pt; margin-bottom:0pt; text-align:center; line-height:125%; widows:0; orphans:0; font-size:14pt\"><b>&nbsp;</b></p><br/>", "");
            return html.replaceAll("src=\"/test/upload/ueditor/image", "src=\"" + rootPath + "test/upload/ueditor/image");
        }
    }

    /**
     * 组装讲义试题，题号自己生成
     * @author 赵文博
     * @date 2021/5/15 15:55
     **/
    public static void createMaterialQuestion(Integer blankRowCount, String subjectId, String rootPath,  QuestionDto question, DocumentBuilder builder, Boolean withTitle, Boolean withAnswer, Boolean withAnalysis, Boolean withExamPoint) throws Exception {
        Integer questionType = _questionTypeRelationService.queryToolQuestionTypeByJyType(question.getSubjectId(), question.getType());
        if (withTitle) {
            // 替换图片路径
            String title = replaceImgPath(rootPath, question.getTitle().trim()).replaceAll("<ol>||</ol>", "").replaceAll("<li", "<p").replaceAll("</li>", "</p>");
//            String questionNo = questionType != null && !questionType.equals(QuestionTypeEnum.READING.getValue()) && !questionType.equals(QuestionTypeEnum.CLOZE.getValue()) ? question.getOrderNo() + 1 + "." : "";
            builder.insertHtml(StringUtils.removeStartAndEndBlank(title));
//            if(!title.endsWith("</p>")){
                builder.writeln();
//            }
        }
        if (questionType == null) {
            questionType = QuestionTypeEnum.OTHER.getValue();
        }
        question.setBasicQuestionType(questionType);
        if (questionType == 1 || questionType == 2) {
            question.setOrderNo(question.getOrderNo() + 1);
            createSingleQuestion(blankRowCount, rootPath, question, builder, withTitle, withAnswer, withAnalysis, withExamPoint);
            return;
        }
        if (questionType == 9) {
            createReadingQuestion(blankRowCount, rootPath, question, builder, withTitle, withAnswer, withAnalysis, withExamPoint);
            return;
        }
        if (questionType == 10) {
            createCloneQuestion(blankRowCount, rootPath, question, builder, withTitle, withAnswer, withAnalysis, withExamPoint);
            return;
        }
        // 其他题型
        question.setOrderNo(question.getOrderNo() + 1);
        if (withAnswer) {
            JSONArray answers = (JSONArray) question.getRightAnswer();
            String answer = "";
            if (answers != null && answers.size() == 1) {
                answer = answers.getJSONObject(0).getString("content");
            }
            // 填空题多个答案
            if (answers != null && answers.size() > 1) {
                for (int i = 0; i < answers.size(); i++) {
                    JSONObject json = answers.getJSONObject(i);
                    answer += "(" + (i + 1) + ")" + json.getString("content");
                    if (i < answers.size() - 1) {
                        answer += "<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
                    }
                }
            }

            String index = withTitle ? "" : question.getOrderNo() + ".";
            builder.insertHtml(index + "【答案】" + answer);
            builder.writeln();
        }
        if (withAnalysis) {
            builder.insertHtml("【解析】" + (question.getAnalysis() == null ? "" : question.getAnalysis()));
            builder.writeln();
        }
        // 解答题留空行
        if (blankRowCount != null && blankRowCount > 0) {
            for (Integer i = 0; i < blankRowCount; i++) {
                builder.writeln();
            }
        }
    }

}
